#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
  if (argc != 2) {
    printf("Using:./server port\nExample:./server 5005\n\n");
    return -1;
  }

  // 第1步：创建服务端的socket。
  int listenfd;
  if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    return -1;
  }

  // 第2步：把服务端用于通信的地址和端口绑定到socket上。
  struct sockaddr_in servaddr;  // 服务端地址信息的数据结构。
  memset(&servaddr, 0, sizeof(servaddr));
  servaddr.sin_family = AF_INET;  // 协议族，在socket编程中只能是AF_INET。
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  // 任意ip地址。
  // servaddr.sin_addr.s_addr = inet_addr("192.168.190.134"); // 指定ip地址。
  servaddr.sin_port = htons(atoi(argv[1]));  // 指定通信端口。
  if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
    perror("bind");
    close(listenfd);
    return -1;
  }

  // 第3步：把socket设置为监听模式。
  if (listen(listenfd, 5) != 0) {
    perror("listen");
    close(listenfd);
    return -1;
  }

  // 第4步：接受客户端的连接。
  int clientfd;                              // 客户端的socket。
  int socklen = sizeof(struct sockaddr_in);  // struct sockaddr_in的大小
  struct sockaddr_in clientaddr;             // 客户端的地址信息。
  clientfd = accept(listenfd, (struct sockaddr *)&clientaddr, (socklen_t *)&socklen);
  printf("客户端(%s)已连接。\n", inet_ntoa(clientaddr.sin_addr));

  // 第5步：与客户端通信。
  int fd = open("dmidecode.txt", O_RDONLY);
  char buffer[4096];
  while (1) {
    int iret;
    memset(buffer, 0, sizeof(buffer));
    read(fd, buffer, sizeof(buffer));
    if (iret = send(clientfd, buffer, strlen(buffer),0))  // 向客户端发送响应结果。
      break;
  }

  // 第6步：关闭socket，释放资源。
  close(listenfd);
  close(clientfd);
}